package com.colorsstudio.defence.baseClass
{
	import adobe.utils.CustomActions;
	import com.colorsstudio.defence.algorithm.AStarLine;
	import com.colorsstudio.defence.algorithm.Waypoint;
	import com.colorsstudio.defence.ConstantValues.Constants;
	import com.colorsstudio.defence.Levels.gameScene1;
	import com.colorsstudio.defence.util.singletonFactory1;
	import de.polygonal.ds.Graph;
	import de.polygonal.ds.GraphNode;
	import de.polygonal.ds.Iterator;
	import de.polygonal.ds.LinkedStack;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.Timer;
	import com.greensock.*;
	import com.greensock.easing.*;
	import idv.cjcat.signals.ISignal;
	import idv.cjcat.signals.Signal;

	/**
	 * ...
	 * @author wuzhida
	 */
	public class Enemy extends MovieClip
	{
		private var point:Point;
		public var graph:Graph;	//地图
		public var startNode:GraphNode; //开始的节点
		public var endNode:GraphNode;//结束的节点
		public var startNodeIndex:int;//开始节点的序号
		public var endNodeIndex:int;//结束节点的序号
		public var pathExists:Boolean;//是否可通
		public var path:LinkedStack;//用栈保存路径
		public var timer:Timer = new Timer(1000, 1);
		public var speed:int = 500;//运动的速度，在tweenlite里面设置
		public var pointsStack:LinkedStack = new LinkedStack();//保存转折点的栈，因为没一个小格都用tweenlite会卡，所以需要计算出转折点，这样会不卡。
		public var moveDir:int;//判断当前移动的方向
		public const HORIZONTAL:int = 1;//水平方向
		public const VERTICAL:int = 2;//垂直方向
		public var currentX:int;//当前的水平X
		public var currentY:int;//当前的垂直Y
		public var health:int =11;//记录总生命值
		public var currentHealth:int = 11;//记录当前生命值
		public var lifeWidth:int = 22;
		public var lifeSprite:Sprite;
		public var enemyArray:Array;
		//记录敌人逃走的扣分
		public var player:Player  = singletonFactory1(Player);
		public var signalFleet:ISignal = new Signal();
		//记录打败敌人的分数
		public var earnScore:int  =10;
		
		public function Enemy(startNodeIndex:int, endNodeIndex:int, graph:Graph, speed:int = 500)
		{
			this.cacheAsBitmap = true;
			this.scaleX = -1;
			lifeSprite = new fl_life();
			lifeSprite.x = -lifeSprite.width / 2;
			lifeSprite.y = -Constants.DEFENCER_HEIGHT/2;
			this.addChild(lifeSprite);
			//this.gotoAndStop(1);
			this.startNodeIndex = startNodeIndex;
			this.endNodeIndex = endNodeIndex;
			this.graph = graph;
			this.speed = speed;
			currentX = startNodeIndex % 16;
			currentY = startNodeIndex / 16;
			startNode = graph.nodes[startNodeIndex];
			endNode = graph.nodes[endNodeIndex];
			pathExists = AStarLine.find(graph, startNode, endNode);
			if (!pathExists)
			{
				//////trace("A HA, the path is not exists!");
				return;
			}
			path = AStarLine.getPath(startNode, endNode);
			caculatePoints();
			this.lifeSprite.width = currentHealth / health * lifeWidth;
		}
		//计算转折点，其实就是从得到的路径里面计算转折点
		public function caculatePoints():void
		{
			pointsStack.clear();
			var endX:int = endNodeIndex % 16;
			var endY:int = endNodeIndex / 16;
			pointsStack.push(new Point(endX,endY));
			var itr:Iterator = path.getIterator();
			var sw:Waypoint = itr.data;
			itr.next();
			var nw:Waypoint;
			moveDir = HORIZONTAL;
			while (itr.hasNext())
			{
				nw = itr.data;
				if (moveDir == HORIZONTAL)
				{
					if ((nw.yIndex - sw.yIndex) == 0)
					{
						
					}
					else
					{
						moveDir = VERTICAL;
						pointsStack.push(new Point(sw.xIndex, sw.yIndex));
					}
				}
				else
				{
					if ((nw.xIndex - sw.xIndex) == 0)
					{
						
					}
					else
					{
						moveDir = HORIZONTAL;
						pointsStack.push(new Point(sw.xIndex, sw.yIndex));
					}
				}
				sw = nw;
				itr.next();
			}
		
		}
		//开始移动enemy
		public function animate():void
		{
			updateTime();
			
			updateAnimation();
		
		}
		//当地图刷新的时候，需要重新计算，这里就是开始的地方
		public function reAnimate(gridX:int,gridY:int):void
		{
			//graph.removeNode(gridX + 16 * gridY);
			//this.gotoAndStop(2);
			//如果用kill的话，那么在敌人运动到那个格子上面的时候，把所有的tweenkill了，会出现问题！
			//TweenLite.killTweensOf(this);
			//////trace("Now we need to recaculate!");
			//首先需要得到当前的x、y格子
			var tx:int =this.x / Constants.DEFENCER_WIDTH-1;
			var ty:int = this.y / Constants.DEFENCER_HEIGHT - 1;
			//trace(tx + "ttttttttttttttt" + ty);
			currentX = tx;
			currentY = ty;
			this.startNodeIndex = tx + ty * 16;
			this.endNodeIndex = endNodeIndex;
			
			//?????????????
			//这里有个bug，当用户在一个格子上面防止塔的时候，这个图里面的node立即就被删除了，可是，当进入到这里的时候
			//仍然需要获得startNode，所以这个startNode会为空，所以，比较好的办法是，首先把这个startNode预先保存下来，然后，
			//相当于先让enemy计算，然后才触发删除图。
			startNode = graph.nodes[startNodeIndex];
			if (startNode == null)
			{
				trace("The startNode is null");
				updateAnimation();
				return;
			}
			endNode = graph.nodes[endNodeIndex];
			
			//trace(startNode.data.xIndex,startNode.data.yIndex);
			//！！！！！！！下面这句是不可以少的，因为这句需要传入一个图的参数，如果不使用这句，下面得到的path也不会更新
			pathExists = AStarLine.find(graph, startNode, endNode);
			if (!pathExists)
			{
				//////trace("A HA, the path is not exists!");
				return;
			}
			//从新得到新的路径数组，返回是一个linkQUEUE
			path = AStarLine.getPath(startNode, endNode);
			//需要计算转折点。
			caculatePoints();
			//重新使用tweenlite进行运动。
			updateAnimation();
		}
		//打算为以后炮弹效果进行更新
		public function updateTime():void
		{
			
		}
		//使用tweenlite进行运动，需要对每一个转折点进行运动
		public function updateAnimation():void
		{
			if (pointsStack.size > 0)
			{
				point = pointsStack.peek();
				pointsStack.pop();
				var timeUse:int = (Math.abs(currentX - point.x) + Math.abs(currentY - point.y)) * speed;
				currentX = point.x;
				currentY = point.y;
				TweenMax.to(this, (timeUse) / 1000, 
				{x: Constants.DEFENCER_WIDTH * (point.x + 1)+20, y: Constants.DEFENCER_HEIGHT * (point.y + 1)+20, ease: Linear.easeNone, onComplete: updateAnimation });
			}
			else
			{
				//trace("escape 1 enemy!");
				if(this.parent!=null)
				{
					player.currentHealth--;
					signalFleet.dispatch();
					enemyArray = gameScene1(this.parent.parent).enemyArray;
					enemyArray.splice(enemyArray.indexOf(this),1);
					this.parent.removeChild(this);					
				}
			}
		}
		
		public function dispose():void
		{			
			this.removeChild(lifeSprite);
			lifeSprite = null;
			this.parent.removeChild(this);
		}
		
		public function pause():void
		{
			TweenMax.pauseAll();
		}
		
		public function unPause():void
		{
			TweenMax.resumeAll();
		}
		
		public function speedUp(num:Number):void
		{
			trace("speedUpEEE");
			TweenMax.globalTimeScale = num;
		}
	}
}